[libc++] Implement exception_ptr on Windows Summary: This patch implements exception_ptr on Windows using the `__ExceptionPtrFoo` functions provided by MSVC. The `__ExceptionPtrFoo` functions are defined inside the C++ standard library, `msvcprt`, which is unfortunate because it requires libc++ to link to the MSVC STL. However this doesn't seem to cause any immediate problems. However to be safe I kept all usages within the libc++ dylib so that user programs wouldn't have to link to MSVCPRT as well. Note there are still 2 outstanding exception_ptr/nested_exception test failures. * `current_exception.pass.cpp` needs to be rewritten for the Windows exception_ptr semantics which copy the exception every time. * `rethrow_if_nested.pass.cpp` need investigation. It hits a stack overflow, likely from recursion. This patch also gets most of the `<future>` tests passing as well. Reviewers: mclow.lists, compnerd, bcraig, rmaprath, majnemer, BillyONeal, STL_MSFT Subscribers: mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D32927 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@302393 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/exception b/include/exception index 9999ca0..ca2eaf5 100644 --- a/include/exception +++ b/include/exception 
@@ -134,23 +134,26 @@  _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;  _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);   +#ifndef _LIBCPP_ABI_MICROSOFT +  class _LIBCPP_TYPE_VIS exception_ptr  {  void* __ptr_;  public:  _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}  _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} +  exception_ptr(const exception_ptr&) _NOEXCEPT;  exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;  ~exception_ptr() _NOEXCEPT;   - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT + {return __ptr_ != nullptr;}    friend _LIBCPP_INLINE_VISIBILITY  bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT  {return __x.__ptr_ == __y.__ptr_;} +  friend _LIBCPP_INLINE_VISIBILITY  bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT  {return !(__x == __y);} @@ -178,6 +181,54 @@  #endif  }   +#else // _LIBCPP_ABI_MICROSOFT + +class _LIBCPP_TYPE_VIS exception_ptr +{ +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-private-field" +#endif + void* __ptr1_; + void* __ptr2_; +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +public: + exception_ptr() _NOEXCEPT; + exception_ptr(nullptr_t) _NOEXCEPT; + exception_ptr(const exception_ptr& __other) _NOEXCEPT; + exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; + exception_ptr& operator=(nullptr_t) _NOEXCEPT; + ~exception_ptr() _NOEXCEPT; + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT; +}; + +_LIBCPP_FUNC_VIS +bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT + {return !(__x == __y);} + +_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; + +_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr); +_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p); + +// This is a built-in template function which automagically extracts the required +// information. +template <class _E> void *__GetExceptionInfo(_E); + +template<class _Ep> +exception_ptr +make_exception_ptr(_Ep __e) _NOEXCEPT +{ + return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e)); +} + +#endif // _LIBCPP_ABI_MICROSOFT  // nested_exception    class _LIBCPP_EXCEPTION_ABI nested_exception